package com.xxmassdeveloper.mpchartexample;

import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Shader;
import android.graphics.Typeface;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.WindowManager;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.widget.Toast;

import com.alibaba.fastjson.JSON;
import com.github.mikephil.charting.animation.Easing;
import com.github.mikephil.charting.charts.Chart;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.LimitLine;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.data.filter.Approximator;
import com.github.mikephil.charting.data.filter.Approximator.ApproximatorType;
import com.github.mikephil.charting.highlight.Highlight;
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
import com.github.mikephil.charting.utils.Utils;
import com.xxmassdeveloper.mpchartexample.custom.MyMarkerView;
import com.xxmassdeveloper.mpchartexample.model.MarkerInfo;
import com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;

import com.xxmassdeveloper.mpchartexample.util.RawUtils;
import java.util.ArrayList;
import java.util.List;

public class LineChartActivity1 extends DemoBase
        implements OnSeekBarChangeListener, OnChartValueSelectedListener {

    private LineChart mChart;
    private SeekBar mSeekBarX, mSeekBarY;
    private TextView tvX, tvY;
    // 线条等颜色
    private int COLOR;
    private List<MarkerInfo> markeInfos;

    /**
     * 禁用掉所有的：包含xy坐标系，图例，网格线，高亮线
     */
    private void disableAll2() {
        mChart.setDescription("");
        mChart.setNoDataTextDescription("");
        // 设置上下左右padding
        mChart.setViewPortOffsets(0, 0, 0, 0);
        XAxis xAxis = mChart.getXAxis();
        // 把X坐标轴放置到底部。默认的是在顶部。
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        //xAxis.enableGridDashedLine(10f, 10f, 0f);
        xAxis.disableGridDashedLine();

        //xAxis.setEnabled(false);
        //// 不显示X标度值
        xAxis.setDrawLabels(false);
        // 不显示X标度线
        xAxis.setDrawAxisLine(false);
        // 不显示X轴网格线
        xAxis.setDrawGridLines(false);

        // X轴坐标线的颜色（是底部标度线颜色，不是网格）
        //xAxis.setAxisLineColor(Color.RED);
        // X轴网格线颜色
        //xAxis.setGridColor(Color.BLUE);

        // 不显示右边的Y坐标轴值
        YAxis rightYAxis = mChart.getAxisRight();
        rightYAxis.setDrawGridLines(false);
        //rightYAxis.setEnabled(false);
        rightYAxis.setDrawAxisLine(false);
        rightYAxis.setDrawLabels(false);
        //rightYAxis.setGridColor(Color.LTGRAY);

        // 不显示左边的Y坐标轴值
        YAxis leftYAxis = mChart.getAxisLeft();
        leftYAxis.setDrawLabels(true);
        leftYAxis.setDrawGridLines(false);
        leftYAxis.setDrawAxisLine(true);
        //leftYAxis.setEnabled(false);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_linechart);
        COLOR = getResources().getColor(R.color.green_lianjia);

        tvX = (TextView) findViewById(R.id.tvXMax);
        tvY = (TextView) findViewById(R.id.tvYMax);

        mSeekBarX = (SeekBar) findViewById(R.id.seekBar1);
        mSeekBarY = (SeekBar) findViewById(R.id.seekBar2);

        markeInfos = JSON.parseArray(RawUtils.getJsonString(this, R.raw.data), MarkerInfo.class);

        //mSeekBarX.setProgress(45);
        //mSeekBarY.setProgress(100);
        //
        //mSeekBarY.setOnSeekBarChangeListener(this);
        //mSeekBarX.setOnSeekBarChangeListener(this);

        mChart = (LineChart) findViewById(R.id.chart1);

        // position是可见范围内的？？并不是所有的
        mChart.setOnMarkClickListener(new Chart.OnMarkClickListener() {
            @Override
            public void clickMark(int position, Entry entry) {
                Toast.makeText(LineChartActivity1.this, "哈哈啊" + position, Toast.LENGTH_SHORT)
                     .show();
            }
        });

        // 设置手势监听
        //mChart.setOnChartGestureListener(null);
        //mChart.setOnChartGestureListener(this);
        mChart.setOnChartValueSelectedListener(this);
        // 是否设置网格背景色，默认显示为Color.rgb(240, 240, 240)
        mChart.setDrawGridBackground(false);
        //mChart.setGridBackgroundColor(Color.RED);

        // no description text
        //mChart.setDescription("哈哈哈");
        mChart.setDescription("");
        mChart.setNoDataTextDescription("");

        // enable touch gestures
        //mChart.setTouchEnabled(true);

        // enable scaling and dragging
        //mChart.setDragEnabled(false);
        //mChart.setScaleEnabled(false);
        // mChart.setScaleXEnabled(true);
        // mChart.setScaleYEnabled(true);

        // if disabled, scaling can be done on x- and y-axis separately
        // 设置上下左右padding
        mChart.setViewPortOffsets(0, 0, 0, 0);
        mChart.setPinchZoom(false); // 双手指时双方向缩放
        //mChart.setMinOffset(0);

        // 设置图表整体水平向右偏移
        //mChart.setExtraLeftOffset(-100);

        // set an alternative background color
        // mChart.setBackgroundColor(Color.BLUE);

        // create a custom MarkerView (extend MarkerView) and specify the layout
        // to use for it
        MyMarkerView mv = new MyMarkerView(this, R.layout.custom_marker_view);

        // set the marker to the chart
        mChart.setMarkerView(mv);
        // 设置背景颜色
        //mChart.setBackgroundColor();

        // x-axis limit line
        //LimitLine llXAxis = new LimitLine(10f, "Index 10");
        //llXAxis.setLineWidth(4f);
        //llXAxis.enableDashedLine(10f, 10f, 0f);
        //llXAxis.setLabelPosition(LimitLabelPosition.RIGHT_BOTTOM);
        //llXAxis.setTextSize(10f);
        //xAxis.addLimitLine(llXAxis); // add x-axis limit line

        XAxis xAxis = mChart.getXAxis();
        // 把X坐标轴放置到底部。默认的是在顶部。
        //xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        //xAxis.enableGridDashedLine(10f, 10f, 0f);
        xAxis.disableGridDashedLine();

        //xAxis.setEnabled(false);
        //// 不显示X标度值
        xAxis.setDrawLabels(false);
        // 不显示X标度线
        xAxis.setDrawAxisLine(false);
        // 不显示X轴网格线
        xAxis.setDrawGridLines(false);

        // X轴坐标线的颜色（是底部标度线颜色，不是网格）
        //xAxis.setAxisLineColor(Color.RED);
        // X轴网格线颜色
        //xAxis.setGridColor(Color.BLUE);

        // 不显示右边的Y坐标轴值
        YAxis rightYAxis = mChart.getAxisRight();
        rightYAxis.setDrawGridLines(false);
        //rightYAxis.setEnabled(false);
        rightYAxis.setDrawAxisLine(false);
        rightYAxis.setDrawLabels(false);
        //rightYAxis.setGridColor(Color.LTGRAY);

        // 不显示左边的Y坐标轴值
        YAxis leftYAxis = mChart.getAxisLeft();
        leftYAxis.setDrawLabels(true);
        leftYAxis.setDrawGridLines(false);
        leftYAxis.setDrawAxisLine(true);
        //leftYAxis.setEnabled(false);
        YAxis leftAxis = mChart.getAxisLeft();
        // 设置最大刻度值为12
        leftAxis.setAxisMaxValue(12);
        //leftAxis.removeAllLimitLines(); // reset all limit lines to avoid overlapping lines
        ////  添加 LimitLine
        //leftAxis.addLimitLine(ll1);
        //leftAxis.addLimitLine(ll2);
        //// 添加最大最小Y轴value线
        //leftAxis.setAxisMaxValue(220f);
        //leftAxis.setAxisMinValue(-50f);
        leftAxis.setStartAtZero(true);
        // Y轴向下偏移，
        //leftAxis.setYOffset(50f);

        //  设置网格的虚线长度（包括线和空格）
        //leftAxis.enableGridDashedLine(10f, 10f, 0f);

        // limit lines are drawn behind data (and not on top)
        leftAxis.setDrawLimitLinesBehindData(true);

        // 设置折线上显示数据的格式。如果不设置，将默认显示float数据格式。
        //mLineDataSet.setValueFormatter(new ValueFormatter() {
        //
        //    @Override
        //    public String getFormattedValue(float value) {
        //        int n = (int) value;
        //        String s = "y:" + n;
        //        return s;
        //    }
        //});


        Typeface tf = Typeface.createFromAsset(getAssets(), "OpenSans-Regular.ttf");

        // 设置limit line
        LimitLine ll1 = new LimitLine(130f, "Upper Limit");
        //ll1.setLineWidth(4f);
        //ll1.enableDashedLine(10f, 10f, 0f);
        //ll1.setLabelPosition(LimitLabelPosition.RIGHT_TOP);
        //ll1.setTextSize(10f);
        //ll1.setTypeface(tf);
        //
        //LimitLine ll2 = new LimitLine(-30f, "Lower Limit");
        //ll2.setLineWidth(4f);
        //ll2.enableDashedLine(10f, 10f, 0f);
        //ll2.setLabelPosition(LimitLabelPosition.RIGHT_BOTTOM);
        //ll2.setTextSize(10f);
        //ll2.setTypeface(tf);



        //mChart.getViewPortHandler().setMaximumScaleY(2f);
        //mChart.getViewPortHandler().setMaximumScaleX(2f);

        //mChart.zoom(4 / 3, 1, 0, 0);
        // 缩放
        mChart.zoom(4 / 3.6f, 1, 0, 0);
        //mChart.setMaxVisibleValueCount();
        // add data
        // TODO 绘制数据
        drawData(markeInfos);

        //        mChart.setVisibleXRange(20);
        //        mChart.setVisibleYRange(20f, AxisDependency.LEFT);
        //        mChart.centerViewTo(20, 50, YAxis.AxisDependency.LEFT);

        //mChart.animateX(TIME_ANIM, Easing.EasingOption.EaseInOutQuart);
                //mChart.invalidate();

        //  图例设置
        Legend mLegend = mChart.getLegend();
        mLegend.setEnabled(false);
        // 图例距离chart左边20px
        //mLegend.setXEntrySpace(20);
        //// 文字与图列图标的偏移量
        //mLegend.setFormToTextSpace(20);
        ////mLegend.setXOffset(50);
        //// 设置图列竖直方向偏移量
        ////mLegend.setYOffset(30);
        //
        //// TODO 如果设置了mLegend.setEnabled(false);
        ////  那么下面四行代码将失效。
        //// 底部居中
        //mLegend.setPosition(Legend.LegendPosition.BELOW_CHART_CENTER);
        //// 格式为圆点
        //mLegend.setForm(LegendForm.CIRCLE);
        //mLegend.setFormSize(8.0f);
        //mLegend.setTextColor(Color.BLUE);

        //  设置标示，就是那个一组y的value的???
        // get the legend (only possible after setting data)
        //Legend l = mChart.getLegend();

        //l.setFormSize(6f); // 字体大小
        //
        //l.setTextColor(Color.RED);

        // modify the legend ...样式
        // l.setPosition(LegendPosition.LEFT_OF_CHART);
        //l.setForm(LegendForm.LINE);

        // // dont forget to refresh the drawing
        // mChart.invalidate();
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.line, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        switch (item.getItemId()) {
            case R.id.actionToggleValues: {
                List<ILineDataSet> sets = mChart.getData().getDataSets();

                for (ILineDataSet iSet : sets) {

                    LineDataSet set = (LineDataSet) iSet;
                    // TODO 设置不显示数值
                    set.setDrawValues(!set.isDrawValuesEnabled());
                }

                mChart.invalidate();
                break;
            }
            case R.id.actionToggleHighlight: {
                if (mChart.getData() != null) {
                    mChart.getData().setHighlightEnabled(!mChart.getData().isHighlightEnabled());
                    mChart.invalidate();
                }
                break;
            }
            // TODO 显示区域阴影（支持设置渐变效果）
            case R.id.actionToggleFilled: {

                List<ILineDataSet> sets = mChart.getData().getDataSets();

                for (ILineDataSet iSet : sets) {

                    LineDataSet set = (LineDataSet) iSet;
                    if (set.isDrawFilledEnabled()) {
                        set.setDrawFilled(false);
                    } else {
                        set.setDrawFilled(true);
                    }
                }
                mChart.invalidate();
                break;
            }
            case R.id.actionToggleCircles: {
                List<ILineDataSet> sets = mChart.getData().getDataSets();

                for (ILineDataSet iSet : sets) {

                    LineDataSet set = (LineDataSet) iSet;
                    if (set.isDrawCirclesEnabled()) {
                        set.setDrawCircles(false);
                    } else {
                        set.setDrawCircles(true);
                    }
                }
                mChart.invalidate();
                break;
            }
            case R.id.actionToggleCubic: {
                List<ILineDataSet> sets = mChart.getData().getDataSets();

                for (ILineDataSet iSet : sets) {

                    LineDataSet set = (LineDataSet) iSet;
                    if (set.isDrawCubicEnabled()) {
                        set.setDrawCubic(false);
                    } else {
                        set.setDrawCubic(true);
                    }
                }
                mChart.invalidate();
                break;
            }
            case R.id.actionToggleStartzero: {
                mChart.getAxisLeft().setStartAtZero(!mChart.getAxisLeft().isStartAtZeroEnabled());
                mChart.getAxisRight().setStartAtZero(!mChart.getAxisRight().isStartAtZeroEnabled());
                mChart.invalidate();
                break;
            }
            case R.id.actionTogglePinch: {
                if (mChart.isPinchZoomEnabled()) {
                    mChart.setPinchZoom(false);
                } else {
                    mChart.setPinchZoom(true);
                }

                mChart.invalidate();
                break;
            }
            case R.id.actionToggleAutoScaleMinMax: {
                mChart.setAutoScaleMinMaxEnabled(!mChart.isAutoScaleMinMaxEnabled());
                mChart.notifyDataSetChanged();
                break;
            }
            case R.id.animateX: {
                //mChart.animateX(3000);
                resetAnim();
                break;
            }
            case R.id.animateY: {
                mChart.animateY(3000, Easing.EasingOption.EaseInCubic);
                break;
            }
            case R.id.animateXY: {
                mChart.animateXY(3000, 3000);
                break;
            }
            case R.id.actionToggleFilter: {

                // the angle of filtering is 35°
                Approximator a = new Approximator(ApproximatorType.DOUGLAS_PEUCKER, 35);

                if (!mChart.isFilteringEnabled()) {
                    mChart.enableFiltering(a);
                } else {
                    mChart.disableFiltering();
                }
                mChart.invalidate();
                break;
            }
            case R.id.actionSave: {
                if (mChart.saveToPath("title" + System.currentTimeMillis(), "")) {
                    Toast.makeText(getApplicationContext(), "Saving SUCCESSFUL!", Toast.LENGTH_SHORT)
                         .show();
                } else {
                    Toast.makeText(getApplicationContext(), "Saving FAILED!", Toast.LENGTH_SHORT)
                         .show();
                }

                // mChart.saveToGallery("title"+System.currentTimeMillis())
                break;
            }
        }
        return true;
    }

    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

        tvX.setText("" + (mSeekBarX.getProgress() + 1));
        tvY.setText("" + (mSeekBarY.getProgress()));

        //setData(mSeekBarX.getProgress() + 1, mSeekBarY.getProgress());

        // redraw
        mChart.invalidate();
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
        // TODO Auto-generated method stub

    }

    /**
     * 存放数据:先initLineData,然后setData,然后resetAnim
     */
    private LineData mLineData;

    /**
     * 初始化数据
     */
    private void initLineData(List<MarkerInfo> markeInfos) {
        // 1.初始化每个节点数据
        ArrayList<String> xVals = new ArrayList<String>();
        ArrayList<Entry> yVals = new ArrayList<Entry>();
        // 水平只是标度值对应的value，内容没有数值的意义
        for (int i = 0; i < markeInfos.size(); i++) {
            xVals.add(String.valueOf(i));
            yVals.add(new Entry(markeInfos.get(i).height, i, markeInfos.get(i)));
        }
        final LineDataSet set1 = new LineDataSet(yVals, "普通line chart");
        // 不绘制yVals
        set1.setDrawValues(false);
        // 设置连接线为虚线
        //set1.enableDashedLine(10f, 5f, 0f);
        // 设置高亮线为虚线
        //set1.enableDashedHighlightLine(10f, 5f, 0f);
        // 设置节点连线的颜色
        set1.setColor(COLOR);

        // 改变折线样式，用曲线，默认false用直线
        // set1.setDrawCubic(true);
        // 曲线的平滑度，值越大越平滑。
        // set1.setCubicIntensity(0.2f);
        // 节点线宽 dp
        set1.setLineWidth(1f);

        // 显示的节点圆圈大小
        set1.setCircleSize(6f);
        // 节点圆圈的颜色
        set1.setCircleColor(Color.WHITE);
        // 允许圆圈中间有洞
        set1.setDrawCircleHole(true);
        // 填充折线上数据点、圆球里面包裹的中心空白处的颜色。
        set1.setCircleColorHole(COLOR);
        //set1.setValueTextSize(9f);
        set1.setFillAlpha(80);
        // 连线封闭区域颜色
        //set1.setFillColor(Color.BLUE);

        // 填充曲线下方的区域，红色，半透明。
        set1.setDrawFilled(false);
        // 由于表格在ScrollView中必须给出高度，所以这里可以写死高度，mChart.getHeight()这里拿不到
        set1.setShader(new LinearGradient(0, 0, 0, Utils.convertDpToPixel(185), Color.parseColor("#7af5c3"), Color.WHITE, Shader.TileMode.MIRROR));
        // // Highlight的十字交叉的横线将不会显示，
        //set1.setDrawHorizontalHighlightIndicator(false);
        // Highlight的十字交叉的纵横线将不会显示，
        set1.setDrawHighlightIndicators(false);
        // 按击后，十字交叉线的颜色
        //set1.setHighLightColor(Color.CYAN);

        // 设置这项上显示的数据点的字体大小。
        //set1.setValueTextSize(10.0f);

        ArrayList<ILineDataSet> dataSets = new ArrayList<ILineDataSet>();
        dataSets.add(set1); // add the datasets

        // create a data object with the datasets
        mLineData = new LineData(xVals, dataSets);
    }

    private int TIME_ANIM = 2500;

    private void resetAnim() {
        if (mLineData == null || mLineData.getDataSets() == null ||
                mLineData.getDataSets().size() == 0) {
            return;
        }
        // 清除全部高亮以及闭合填充
        mChart.highlightValues(null);
        mLineData.getDataSets().get(0).setDrawFilled(false);
        // 这个动画会保留之前的所有状态从左到有一次显示
        mChart.animateX(TIME_ANIM, Easing.EasingOption.EaseInOutQuart);
        //mChart.animateX(TIME_ANIM);

        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                // 动画结束后再设置填充以及绘制markview
                mLineData.getDataSets().get(0).setDrawFilled(true);
                mChart.highlightAllValues();
            }
        }, TIME_ANIM);
    }

    private void setData() {
        // set data，填充数据
        mChart.setData(mLineData);
        // 移动几个x的位置，如果放大要根据放大比例
        mChart.moveViewToX(2.0f / 9);
        //mChart.moveViewToX(0.5f);
        //resetAnim(lineData);
    }

    /**
     * 绘制数据
     *
     * @param markeInfos
     */
    private void drawData(List<MarkerInfo> markeInfos) {
        initLineData(markeInfos);
        setData();
        resetAnim();
    }

    /**
     * 禁用掉所有的：包含xy坐标系，图例，网格线，高亮线
     */
    private void disableAll() {

    }

    @Override
    public void onValueSelected(Entry e, int dataSetIndex, Highlight h) {
        Log.i("Entry selected", e.toString());
        Log.i("", "low: " + mChart.getLowestVisibleXIndex() + ", high: " +
                mChart.getHighestVisibleXIndex());
    }

    @Override
    public void onNothingSelected() {
        Log.i("Nothing selected", "Nothing selected.");
    }
}
